package de.gameduell.framework.application {

	import de.gameduell.framework.util.FlashVars;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;		

	/**
	 * Parse and hold settings of an application.
	 * All these settings can be set up via the <b>config.xml</b> which is
	 * usually used by any GameDuell AS3 flash application.
	 */
	public class Settings {

		/** default framerate (fps) of an application. Can be adjusted via confix.xml */
		public static const DEFAULT_FRAME_RATE:int  = 25; 

		/** socket connection: default time between two sync messages which will be sent to the server. Can be adjusted via confix.xml */
		public static const DEFAULT_SOCKET_SYNC:int = 20000;
		
		/** poll connection: default time between two sync messages which will be sent to the server. Can be adjusted via confix.xml */
		public static const DEFAULT_POLL_SYNC:int   = 2000;

		private var _framerate:int;
		private var _socketSync:int;
		private var _pollSync:int;
		private var _gameversion:String;
		private var _protocol:String;
		private var _gameType:String;
		private var _standalone:Boolean;
		private var _chatExists:Boolean;
		private var _maxTutorialTime:int;
		private var _useGeneralLang:Boolean;
		private var _dumpErrorToServer:Boolean;
		private var _scaleMode:String;
		private var _stageAlign:String;
		private var _sendScore:Boolean;
		private var _encryptScore:Boolean;
		private var _scoreParam:String;
		private var _sendScoreURL:String;
		private var _sendScoreMethod:String;
		private var _activeLanguages:Array;

		/**
		 * Parse all settings from an already loaded config file.
		 * Some of them are optional and will be replaced by defaults.
		 * 
		 * @param settings	content of the loaded config.xml file
		 */
		public function Settings(settings:XMLList){
			_framerate         = String(settings.child("framerate")) != "" ? int(settings.child("framerate")) : DEFAULT_FRAME_RATE;
			_socketSync        = String(settings.child("socketsync")) != "" ? int(settings.child("socketsync")) : DEFAULT_SOCKET_SYNC;
			_pollSync          = String(settings.child("pollsync")) != "" ? int(settings.child("pollsync")) : DEFAULT_POLL_SYNC;
			_gameversion       = settings.child("gameversion");
			_protocol          = settings.child("protocol");
			_gameType          = settings.child("gametype");
			_standalone        = settings.child("standalone") == "true";
			_useGeneralLang    = settings.child("useGeneralLangFile") != "false";
			_chatExists        = checkChat(settings);
			_maxTutorialTime   = int(settings.child("maxTutorialTime"));
			_activeLanguages   = String(settings.child("activeLanguages")).split(",");
			
			var dumpErrorToServer:String = settings.child("dumpErrorToServer") == FlashVars.NO_VALUE ? "true" : settings.child("dumpErrorToServer");
			_dumpErrorToServer = dumpErrorToServer == "true";
			
			_sendScore         = settings.child("sendScore") == "true";
			_sendScoreURL      = String(settings.child("sendScore").attribute("urlParam"));
			_scoreParam        = String(settings.child("sendScore").attribute("scoreParam"));
			_encryptScore      = String(settings.child("sendScore").attribute("encrypted")) == "true";
			_sendScoreMethod   = String(settings.child("sendScore").attribute("method")) == "js" ? "js" : "url";
			_stageAlign        = String(settings.child("stageAlign")) != "" ? String(settings.child("stageAlign")) : StageAlign.TOP_LEFT;
			_scaleMode         = String(settings.child("scaleMode")) != "" ? String(settings.child("scaleMode")) : StageScaleMode.NO_SCALE;
		}
		
		/**
		 * Since the chat option can be handled separatly for each country,
		 * this function enables / disables the chat option of an application
		 * depending on the language/country.
		 * <br>
		 * The result will be stored in -> chatExists()<br>
		 * <b>Usage:</b> &lt;settings&gt;&lt;chatExists&gt;de,fr,en,es,nl etc.&lt;/chatExists&gt;&lt;/settings&gt;
		 * 
		 * @param settings	XMLList with settings for each country
		 */
		private function checkChat(settings:XMLList):Boolean{
			var chatEnabledNode:String = String(settings.child("chatExists"));
			var hasChat:Boolean = false;
			if(chatEnabledNode != null){
				var chatCountries:Array = chatEnabledNode.split(",");
				for(var i:* in chatCountries){
					if(FlashVars.getKeyValue(FlashVars.LANGUAGE) == chatCountries[i]){
						hasChat = true;
					}
				}
			}
			return hasChat;
		}
		
		/**
		 * Right before an application redirects to another website the score will be sent to this url.
		 * <b>Usage:</b> &lt;settings&gt;&lt;sendScore scoreParam="score" urlParam="targetURL"&gt;true or false&lt;/sendScore&gt;&lt;/settings&gt;
		 * 
		 * @return the target URL for optional score dumping
		 */
		public function get sendScoreURL():String {
			return FlashVars.getKeyValue(_sendScoreURL) == FlashVars.NO_VALUE ? null : FlashVars.getKeyValue(_sendScoreURL); 
		}

		/**
		 * Right before an application redirects to another website the score
		 * will be sent to the 'dumpScoreURL.<br>
		 * <b>Usage:</b> &lt;settings&gt;&lt;sendScore scoreParam="score" urlParam="targetURL"&gt;true or false&lt;/sendScore&gt;&lt;/settings&gt;
		 * 
		 * @return true if dumping enabled.
		 */
		public function get sendScore():Boolean {
			return _sendScore;
		}
		
		public function get activeLanguages():Array {
			return _activeLanguages;
		}
		
		public function get encryptScore():Boolean {
			return _encryptScore;
		}
		
		public function get sendScoreMethod():String {
			return _sendScoreMethod;
		}

		/**
		 * Name of the score parameter which will be set by the Frontend.
		 * <b>Usage:</b> &lt;settings&gt;&lt;sendScore scoreParam="score" urlParam="targetURL"&gt;true or false&lt;/sendScore&gt;&lt;/settings&gt;
		 * 
		 * @return name for frontend score parameter
		 */
		public function get scoreParam():String {
			return _scoreParam;
		}

		/**
		 * <b>Usage:</b> &lt;settings&gt;&lt;scaleMode&gt;a scale mode&lt;/scaleMode&gt;&lt;/settings&gt;<br>
		 * default is -> StageScaleMode.NO_SCALE
		 * 
		 * @return scale mode of the flash stage.
		 */
		public function get scaleMode():String {
			return _scaleMode;
		}
		
		/**
		 * <b>Usage:</b> &lt;settings&gt;&lt;stageAlign&gt;align string&lt;/stageAlign&gt;&lt;/settings&gt;<br>
		 * default is -> StageAlign.TOP_LEFT
		 * 
		 * @return alignment of the flash stage.
		 */
		public function get stageAlign():String {
			return _stageAlign;
		}
		
		/**
		 * @return true if an application has a chat option.
		 */
		public function get chatExists():Boolean{
			return _chatExists;
		}

		/**
		 * This setting overrides any in FLA files values.<br>
		 * default is ->  25 fps<br>
		 * maximum is -> 120 fps<br>
		 * <b>Usage:</b> &lt;settings&gt;&lt;framerate&gt;int values 1 to 120&lt;/framerate&gt;&lt;/settings&gt;
		 * 
		 * @return the framerate (fps - frames per second) of an application.
		 */
		public function get framerate():int {
			return _framerate;
		}

		/**
		 * default is -> 20000 milliseconds<br>
		 * <b>Usage:</b> &lt;settings&gt;&lt;socketsync&gt;time in milliseconds&lt;/socketsync&gt;&lt;/settings&gt;
		 * 
		 * @return the socketConnection sync interval.
		 */
		public function get socketSync():int {
			return _socketSync;
		}

		/**
		 * default is -> 2000 milliseconds<br>
		 * <b>Usage:</b> &lt;settings&gt;&lt;pollsync&gt;time in milliseconds&lt;/pollsync&gt;&lt;/settings&gt;
		 * 
		 * @return the pollConnection interval.
		 */
		public function get pollSync():int {
			return _pollSync;
		}

		/**
		 * For AS3 games which are using the framework, it's currently '-0.0.1'.<br>
		 * <b>Usage:</b> &lt;settings&gt;&lt;gameversion&gt;a version&lt;/gameversion&gt;&lt;/settings&gt;
		 * 
		 * @return the used gameversion string for the client/server connection.
		 */
		public function get gameVersion():String {
			return _gameversion;
		}

		/**
		 * For AS3 games which are using the framework, it's typically 'V2'.<br>
		 * <b>Usage:</b> &lt;settings&gt;&lt;protocol&gt;V2&lt;/protocol&gt;&lt;/settings&gt;
		 * 
		 * @return the used communication protocol for the client/server connection.
		 */
		public function get protocol():String {
			return _protocol;
		}

		/**
		 * <b>Usage:</b> &lt;settings&gt;&lt;gametype&gt;your gametype&lt;/gametype&gt;&lt;/settings&gt;
		 * 
		 * @return the current gametype / application type
		 */
		public function get gameType():String {
			return _gameType;
		}
		
		/**
  		 * If an application runs as standalone, it's gonna using standalone.swf instead of communication.swf.
		 * An application is automatically standalone if you run it local from a filesystem.<br>
		 * 
		 * <b>Usage:</b> &lt;settings&gt;&lt;standalone&gt;true or false&lt;/standalone&gt;&lt;/settings&gt;
		 * 
		 * @return if an application runs as standalone
		 */
		public function get standalone():Boolean {
			return _standalone;
		}

		/**
		 * If true, a second language content file will be added to the loader queue.<br>
		 * <b>Usage:</b> &lt;settings&gt;&lt;useGeneralLangFile&gt;true or false&lt;/useGeneralLangFile&gt;&lt;/settings&gt;
		 * 
		 * default is -> true
		 */		
		public function get useGeneralLangFile():Boolean {
			return _useGeneralLang;
		}

		/**
		 * If true, an application is able to send an error request to the gameserver.
		 * This message can be found in the flash_r.log file.<br>
		 * <b>Usage:</b> &lt;settings&gt;&lt;dumpErrorToServer&gt;true or false&lt;/dumpErrorToServer&gt;&lt;/settings&gt;<br>
		 * 
		 * default is -> false
		 */		
		public function get dumpErrorToServer():Boolean {
			return _dumpErrorToServer;
		}

		/**
		 * The time a tutorial is max. displayed.
		 * If this time runs out, the application starts and the tutorial will be removed.<br>
		 * <b>Usage:</b> &lt;settings&gt;&lt;maxTutorialTime&gt;an int value in milliseconds&lt;/maxTutorialTime&gt;&lt;/settings&gt;
		 */	
		public function get maxTutorialTime():int {
			return _maxTutorialTime;
		}
	}
}